/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package game;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.icefaces.application.PushRenderer;
import other.Costants;

/**
 *
 * @author alessandro
 */
public class Table implements Serializable {
    private List<String> userWatching = new ArrayList<String>();
    private List<String> userPlaying = new ArrayList<String>();
    private List<BOT> botPlaying = new ArrayList<BOT>();

    private String status;
    private String creator;
    private int bots;
    private String name;
    private String message;
    private Deck deck;

    public Table(String creator, int bots, String name) {
        this.message = Costants.TABLE_WELCOME;
        this.addBots(bots);
        this.creator = creator;
        this.status = Costants.READY;
        deck = new Deck();       
        this.name = name;
    }


    /* GETTERS AND SETTERS */

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    
    public int getUserWatchingNumber() {
        return userWatching.size();
    }

    public int getUserPlayingNumber() {
        return userPlaying.size();
    }

    public List<BOT> getBotPlaying() {
        return botPlaying;
    }

    public void setBotPlaying(List<BOT> botPlaying) {
        this.botPlaying = botPlaying;
    }

    public String getCreator() {
        return creator;
    }

    public void setCreator(String creator) {
        this.creator = creator;
    }

    public Deck getDeck() {
        return deck;
    }

    public void setDeck(Deck deck) {
        this.deck = deck;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getBots() {
        return bots;
    }

    public void setBots(int bots) {
        this.bots = bots;
    }

    public List<String> getUserPlaying() {
        return userPlaying;
    }

    public void setUserPlaying(List<String> userPlaying) {
        this.userPlaying = userPlaying;
    }

    public List<String> getUserWatching() {
        return userWatching;
    }

    public void setUserWatching(List<String> userWatching) {
        this.userWatching = userWatching;
    }

    /* METODI */

    private void addBots(int bots) {
        for(int i=0; i < bots; i++) {
            botPlaying.add(new BOT(Costants.BOTNAME+i));
        }
    }

    public void setNewUserWatching(String user) {
        if (!(this.isWatching(user))) {
            userWatching.add(user);
        }
    }
    public void revomeUserWatching(String user) {
        userWatching.remove(user);
    }

    public void removeUserPlaying(String user) {
        userPlaying.remove(user);
    }
    public boolean isWatching(String user) {
        boolean flag = false;
        for(int i=0; i<userWatching.size(); i++) {
            if(userWatching.get(i).equals(user)){
                flag = true;
                return flag;
            }
        }
        return flag;
    }

    public boolean isPlaying(String user) {
        boolean flag = false;
        for (int i = 0; i < userPlaying.size(); i++) {
            if (userPlaying.get(i).equals(user)) {
                flag = true;
                return flag;
            }
        }
        return flag;
    }

    public boolean isFull() {
        boolean flag = false;
        if(this.getPlayersList().size() == 4){
            flag = true;
        }
        return flag;
    }

    public int getPlayers() {
        return Costants.MAX_PLAYERS - bots;
    }

    public List<String> getPlayersList() {
        List<String> players = new ArrayList<String>();
        if (userPlaying.size() > 0) {
            players.addAll(userPlaying);
        }
        for (int i = 0; i < botPlaying.size(); i++) {
            players.add(botPlaying.get(i).getName());
        }

        return players;
    }

    public int getPlayersNumber() {
        return this.getPlayersList().size();
    }    

    public boolean isStarted() {
        if(this.status.equals(Costants.STARTED)) 
            return true;
         else
            return false;
    }
    public BOT getBotByName(String name){
        BOT bot = null;
        for (int i = 0; i< botPlaying.size(); i++) {
            if(botPlaying.get(i).getName().equals(name))
                bot = botPlaying.get(i);
        }
        return bot;
    }
    public void addUserPlaying(String username) {
        if (!(this.isPlaying(username))) {
            userPlaying.add(username);
            if (this.isFull()) {
                System.out.println("THE GAME IS RUN!");
                this.startGame();
            }
        }
    }

    public void startGame() {
        status = Costants.STARTED;
        deck.shuffleCards();
        deck.startGivingCards();

        message = Costants.TABLE_GAME_START + " 3..";
        PushRenderer.render(Costants.PUSH_TABLE);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Table.class.getName()).log(Level.SEVERE, null, ex);
        }
        message = Costants.TABLE_GAME_START + " 2..";
        PushRenderer.render(Costants.PUSH_TABLE);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Table.class.getName()).log(Level.SEVERE, null, ex);
        }
         message = Costants.TABLE_GAME_START + " 1..";
        PushRenderer.render(Costants.PUSH_TABLE);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Table.class.getName()).log(Level.SEVERE, null, ex);
        }

        message = Costants.TABLE_PLAYER_TURN + " " + this.getPlayersList().get(deck.getToken());
        PushRenderer.render(Costants.PUSH_TABLE);

        this.checkTurn();

    }

    public void checkTurn() {
        //vedo se il giocatore che deve giocare è un bot
        if(this.getPlayersList().get(deck.getToken()).contains(Costants.BOTNAME)) {
            BOT bot = this.getBotByName(this.getPlayersList().get(deck.getToken()));
            Card card = null;
            switch(deck.getToken()) {
                case 0:
                    card = bot.play(deck.getCardsPlayer1());
                    card.setState(Costants.ON_TABLE);
                    deck.getCardsPlayer1().remove(card);
                    deck.getCardsPlayer1().add(card);
                    System.out.println("Giocatore 1 play:" + card.getSeed() + card.getNumber());
                    System.out.println("ULTIMA CARTA GIOCATORE 1:"+deck.getCardsPlayer1().get(deck.getCardsPlayer1().size()-1).getSeed());
                    break;
                case 1:
                    card = bot.play(deck.getCardsPlayer2());
                    card.setState(Costants.ON_TABLE);
                    deck.getCardsPlayer2().remove(card);
                    deck.getCardsPlayer2().add(card);
                    System.out.println("Giocatore 2 play:" + card.getSeed() + card.getNumber());
                    System.out.println("ULTIMA CARTA GIOCATORE 2:"+deck.getCardsPlayer2().get(deck.getCardsPlayer2().size()-1).getSeed());
                    break;
                case 2:
                    card = bot.play(deck.getCardsPlayer3());
                    card.setState(Costants.ON_TABLE);
                    deck.getCardsPlayer3().remove(card);
                    deck.getCardsPlayer3().add(card);
                    System.out.println("Giocatore 3 play:" + card.getSeed() + card.getNumber());
                    System.out.println("ULTIMA CARTA GIOCATORE 3:"+deck.getCardsPlayer3().get(deck.getCardsPlayer3().size()-1).getSeed());
                    break;
                case 3:
                    card = bot.play(deck.getCardsPlayer4());
                    card.setState(Costants.ON_TABLE);
                    deck.getCardsPlayer4().remove(card);
                    deck.getCardsPlayer4().add(card);
                    System.out.println("Giocatore 4 play:" + card.getSeed() + card.getNumber());
                    System.out.println("ULTIMA CARTA GIOCATORE 4:"+deck.getCardsPlayer4().get(deck.getCardsPlayer4().size()-1).getSeed());
                    break;
            }
            System.out.println("CARTA GIOCATA " + card.getSeed() + card.getNumber());
            
            PushRenderer.render(Costants.PUSH_TABLE);
            deck.setToken(deck.getToken() + 1);
            checkTurn();
        }
    }

    public Card getCardonTable(String username) {
        Card card = null;

        ArrayList<Card> cards = this.getCardsPlayer(username);
        if(cards != null) {
            for(int i = 0; i < cards.size(); i++) {
                if(cards.get(i).getState().equals(Costants.ON_TABLE)) {
                    System.out.println("CARTA di " + username + ": "+ cards.get(i).getSeed() + cards.get(i).getNumber() + " stato:" + cards.get(i).getState());
                    return cards.get(i);
                }
            }
        }

        return card;
    }

    public int getPlayerId(String username) {
        int id = -1;

        for (int i = 0; i < this.getPlayersList().size(); i++) {
            if(this.getPlayersList().get(i).equals(name)) {
                return i;
            }
        }

        return id;
    }


    /* cerca le carte possedute da un giocatore dal suo nickname */
    public ArrayList<Card> getCardsPlayer(String username) {
                ArrayList<Card> cards = null;
        int playerId = this.getPlayerId(username);
        switch(playerId) {
            case -1:
                return null;
            case 0:
                 System.out.println(username + " id:" + this.getPlayerId(username) + "Prima Carta:" + deck.getCardsPlayer1().get(deck.getCardsPlayer1().size()-1).getSeed() + deck.getCardsPlayer1().get(deck.getCardsPlayer1().size()-1).getNumber());
                return deck.getCardsPlayer1();
            case 1:
                System.out.println(username + " id:" + this.getPlayerId(username) + "Prima Carta:" +deck.getCardsPlayer2().get(deck.getCardsPlayer2().size()-1).getSeed() + deck.getCardsPlayer2().get(deck.getCardsPlayer2().size()-1).getNumber());
                return deck.getCardsPlayer2();

            case 2:
                System.out.println(username + " id:" + this.getPlayerId(username) + "Prima Carta:" + deck.getCardsPlayer3().get(deck.getCardsPlayer3().size()-1).getSeed() + deck.getCardsPlayer3().get(deck.getCardsPlayer3().size()-1).getNumber());
                return deck.getCardsPlayer3();
            case 3:
                System.out.println(username + " id:" + this.getPlayerId(username) + "Prima Carta:" + deck.getCardsPlayer4().get(deck.getCardsPlayer4().size()-1).getSeed() + deck.getCardsPlayer4().get(deck.getCardsPlayer4().size()-1).getNumber());
                return deck.getCardsPlayer4();
        }

        return cards;
    }

    public Card getOnTableCard(ArrayList<Card> cards) {
        Card card = null;
        if(cards != null) {
            for(int i = 0; i < cards.size(); i++) {
                if(cards.get(i).getState().equals(Costants.ON_TABLE)) {
                    return cards.get(i);
                }
            }
        }
        return card;
    }

    public boolean play(String username, String card) {
        boolean flag = false;

        /* controlli */
        ArrayList<Card> cards = this.getCardsPlayer(username);





        return flag;
    }
}
